package com.sikaryofficial.adaptermq.constant;

import cn.hutool.core.util.ClassUtil;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sikaryofficial.adaptermq.domain.entity.*;
import com.sikaryofficial.adaptermq.service.*;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author : qinjinyuan
 * @desc : 数据库表与类映射关系
 * @date : 2023/11/04 10:08
 */
@Getter
@AllArgsConstructor
public enum TableMapperEnum {
    /**
     *
     */
    ARTICLE(IArticleService.class, Article.class),
    ARTICLE_CATEGORY(IArticleCategoryService.class, ArticleCategory.class),
    ARTICLE_CATEGORY_MAPPER(IArticleCategoryMappingService.class, ArticleCategoryEntity.class),
    ARTICLE_EVALUATE(IArticleEvaluateService.class, ArticleEvaluate.class),
    ARTICLE_EVALUATE_REPLY(IArticleEvaluateReplyService.class, ArticleEvaluateReply.class),
    ARTICLE_EXPOSURE_DAILY(IArticleExposureCountService.class, ArticleExposureCount.class),
    ARTICLE_VIEWS(IArticleViewsService.class, ArticleViews.class),

    FOLLOW(IFollowService.class, Follow.class),
    MY_STATISTICS(IMyStatisticsService.class, MyStatistics.class),
    USER_ACTION(IUserActionService.class, UserAction.class),
    USER_SHIELD(IUserShieldService.class, UserShield.class),

    ATTACHMENT(IAttachmentService.class, Attachment.class),

    SYS_USER(ISysUserService.class, SysUser.class),

    SYS_USER_DAILY(ISysUserDailyService.class, SysUserDaily.class),

    /**
     * 新增2张表
     */
    GOODS(IGoodsService.class, Goods.class),
    GOODS_RELATION(IGoodsRelationService.class, GoodsRelation.class)
    ;


    /**
     * 要扫描的包名
     */
    private static final String PACKAGE_NAME = "com.sikaryofficial.adaptermq.domain.entity";

    private final Class<?> clazz;
    private final Class<?> entityClazz;

    public static TableMapperEnum getByClazz(Class<?> clazz) {
        return Arrays.stream(TableMapperEnum.values())
                .filter(pointRuleEnum -> pointRuleEnum.getEntityClazz().equals(clazz))
                .findFirst().orElse(null);
    }

    /**
     * 构建表名 与枚举关系
     *
     * @return
     */
    public static Map<String, TableMapperEnum> buildAllTableInfo() {
        // 获取指定包下所有类
        Set<Class<?>> classes = ClassUtil.scanPackage(PACKAGE_NAME);
        // 遍历类，检查是否有指定注解
        Map<String, TableMapperEnum> tableMapperEnumMap = new HashMap<>();
        Set<Class<?>> configClasses = Arrays.stream(TableMapperEnum.values()).map(TableMapperEnum::getEntityClazz)
                .collect(Collectors.toSet());
        for (Class<?> clazz : classes) {
            // 在这里可以进一步处理找到的类，比如获取注解实例等
            TableName clazzAnnotation = clazz.getAnnotation(TableName.class);
            if (!configClasses.contains(clazz) || Objects.isNull(clazzAnnotation)) {
                continue;
            }
            buildMapperData(tableMapperEnumMap, clazz, clazzAnnotation);
        }
        return tableMapperEnumMap;
    }

    private static void buildMapperData(Map<String, TableMapperEnum> tableMapperEnumMap, Class<?> clazz, TableName clazzAnnotation) {
        String tableName = clazzAnnotation.value();
        TableMapperEnum curEnum = getByClazz(clazz);
        if (Objects.nonNull(curEnum) && hasCustomAnnotation(clazz)) {
            tableMapperEnumMap.put(tableName, curEnum);
        }
    }

    /**
     * 检查类是否包含指定的自定义注解。
     *
     * @param clazz 类
     * @return 类上是否存在该自定义注解
     */
    private static boolean hasCustomAnnotation(Class<?> clazz) {
        // 获取自定义注解的Class对象
        // 检查类、方法、字段上是否有该注解
        return clazz.isAnnotationPresent(TableName.class);
    }
}